// ThreadPool_test.cc - 线程池单元测试
// 测试线程池的各种功能和边界条件

#include "base/ThreadPool.h"
#include <gtest/gtest.h>
#include <atomic>
#include <chrono>
#include <functional>
#include <iostream>
#include <memory>
#include <string>
#include <thread>
#include <vector>

namespace cytoolkit {
namespace test {

// 基本功能测试
TEST(ThreadPoolTest, BasicFunctionality) {
    // 创建4个线程的线程池
    ThreadPool pool(4, "TestPool");
    pool.start();
    
    // 原子计数器，用于验证任务执行次数
    std::atomic<int> counter(0);
    const int kNumTasks = 100;
    
    // 提交任务
    std::vector<std::future<void>> futures;
    for (int i = 0; i < kNumTasks; ++i) {
        futures.push_back(pool.submit([&counter]() {
            ++counter;
        }));
    }
    
    // 等待所有任务完成
    for (auto& future : futures) {
        future.wait();
    }
    
    // 验证所有任务都被执行
    EXPECT_EQ(counter, kNumTasks);
    
    // 关闭线程池
    pool.shutdown();
}

// 带返回值的任务测试
TEST(ThreadPoolTest, TaskWithReturnValue) {
    ThreadPool pool(2, "ReturnTestPool");
    pool.start();
    
    // 提交带返回值的任务
    auto future1 = pool.submit([]() {
        return 42;
    });
    
    auto future2 = pool.submit([](int a, int b) {
        return a + b;
    }, 10, 20);
    
    // 验证返回值
    EXPECT_EQ(future1.get(), 42);
    EXPECT_EQ(future2.get(), 30);
    
    pool.shutdown();
}

// 无返回值的任务执行测试
TEST(ThreadPoolTest, ExecuteWithoutReturnValue) {
    ThreadPool pool(3, "ExecuteTestPool");
    pool.start();
    
    std::atomic<int> counter(0);
    const int kNumTasks = 50;
    
    // 执行无返回值的任务
    for (int i = 0; i < kNumTasks; ++i) {
        pool.execute([&counter]() {
            ++counter;
        });
    }
    
    // 等待任务完成
    pool.waitForTasks();
    
    // 验证所有任务都被执行
    EXPECT_EQ(counter, kNumTasks);
    
    pool.shutdown();
}

// 线程池状态测试
TEST(ThreadPoolTest, StateManagement) {
    ThreadPool pool(2, "StateTestPool");
    
    // 初始状态应为kRunning
    EXPECT_EQ(pool.state(), ThreadPoolState::kRunning);
    
    pool.start();
    
    // 启动后状态仍为kRunning
    EXPECT_EQ(pool.state(), ThreadPoolState::kRunning);
    
    // 提交一些任务
    for (int i = 0; i < 5; ++i) {
        pool.execute([]() {
            std::this_thread::sleep_for(std::chrono::milliseconds(10));
        });
    }
    
    // 关闭线程池
    pool.shutdown();
    
    // 关闭后状态应为kTerminated
    EXPECT_EQ(pool.state(), ThreadPoolState::kTerminated);
}

// 任务队列大小测试
TEST(ThreadPoolTest, QueueSize) {
    ThreadPoolOptions options;
    options.name = "QueueSizeTestPool";
    options.initialThreads = 1;
    options.maxThreads = 1;
    options.maxQueueSize = 4; // 设置最大队列大小为4
    
    ThreadPool pool(options);
    pool.start();
    
    // 提交任务到队列
    std::vector<std::future<void>> futures;
    for (int i = 0; i < 5; ++i) {
        futures.push_back(pool.submit([i]() {
            // 长时间任务，使队列积累
            std::this_thread::sleep_for(std::chrono::milliseconds(100));
        }));
    }
    
    // 短暂等待，确保任务被放入队列
    std::this_thread::sleep_for(std::chrono::milliseconds(10));
    
    // 验证队列已满
    EXPECT_TRUE(pool.isFull());
    EXPECT_FALSE(pool.isEmpty());
    EXPECT_EQ(pool.queueSize(), 4); // 提交了5个任务，队列容量为4，所以队列大小为4
    
    // 等待任务完成
    for (auto& future : futures) {
        future.wait();
    }
    
    // 验证队列为空
    EXPECT_TRUE(pool.isEmpty());
    EXPECT_FALSE(pool.isFull());
    EXPECT_EQ(pool.queueSize(), 0);
    
    pool.shutdown();
}

// 线程池大小调整测试
TEST(ThreadPoolTest, Resize) {
    ThreadPool pool(2, "ResizeTestPool");
    pool.start();
    
    // 初始线程数
    EXPECT_EQ(pool.threadCount(), 2);
    
    // 增加线程数
    EXPECT_TRUE(pool.resize(4));
    EXPECT_EQ(pool.threadCount(), 4);
    
    // 尝试增加到更大的值
    EXPECT_TRUE(pool.resize(6));
    EXPECT_EQ(pool.threadCount(), 6);
    
    pool.shutdown();
}

// 并发压力测试
TEST(ThreadPoolTest, ConcurrentStress) {
    const size_t kThreads = 8;
    const size_t kTasksPerThread = 100;
    const size_t kTotalTasks = kThreads * kTasksPerThread;
    
    ThreadPool pool(kThreads, "StressTestPool");
    pool.start();
    
    std::atomic<size_t> completedTasks(0);
    std::vector<std::future<void>> futures;
    
    // 提交大量并发任务
    for (size_t i = 0; i < kTotalTasks; ++i) {
        futures.push_back(pool.submit([&completedTasks]() {
            // 模拟一些计算工作
            volatile int sum = 0;
            for (int j = 0; j < 1000; ++j) {
                sum += j;
            }
            
            // 增加完成任务计数
            ++completedTasks;
        }));
    }
    
    // 等待所有任务完成
    for (auto& future : futures) {
        future.wait();
    }
    
    // 验证所有任务都已完成
    EXPECT_EQ(completedTasks, kTotalTasks);
    
    pool.shutdown();
}

// 异常处理测试
TEST(ThreadPoolTest, ExceptionHandling) {
    ThreadPool pool(2, "ExceptionTestPool");
    pool.start();
    
    // 提交会抛出异常的任务
    auto future = pool.submit([]() {
        throw std::runtime_error("Test exception");
        return 42; // 永远不会执行到这里
    });
    
    // 验证异常被正确传播
    EXPECT_THROW(future.get(), std::runtime_error);
    
    // 确保线程池仍然可以正常工作
    auto future2 = pool.submit([]() {
        return 100;
    });
    
    EXPECT_EQ(future2.get(), 100);
    
    pool.shutdown();
}

// 立即关闭测试
TEST(ThreadPoolTest, ShutdownNow) {
    ThreadPoolOptions options;
    options.initialThreads = 1;
    options.maxThreads = 1;
    options.maxQueueSize = 10;
    
    ThreadPool pool(options);
    pool.start();
    
    // 提交一个长时间运行的任务
    auto longRunningFuture = pool.submit([]() {
        std::this_thread::sleep_for(std::chrono::seconds(10));
        return 42;
    });
    
    // 提交一些队列中的任务
    for (int i = 0; i < 5; ++i) {
        pool.execute([]() {
            std::this_thread::sleep_for(std::chrono::milliseconds(100));
        });
    }
    
    // 短暂等待，确保第一个任务开始执行
    std::this_thread::sleep_for(std::chrono::milliseconds(50));
    
    // 立即关闭线程池
    pool.shutdownNow();
    
    // 验证状态为终止
    EXPECT_EQ(pool.state(), ThreadPoolState::kTerminated);
    
    // 注意：长时间运行的任务可能已经被中断，future可能会抛出异常
}

// 清空任务队列测试
TEST(ThreadPoolTest, ClearTasks) {
    ThreadPoolOptions options;
    options.initialThreads = 1;
    options.maxThreads = 1;
    options.maxQueueSize = 10;
    options.allowCoreThreadTimeout = true;
    options.keepAliveTimeMs = 100; // 短超时，方便测试
    
    ThreadPool pool(options);
    pool.start();
    
    // 提交一些任务
    pool.execute([]() {
        std::this_thread::sleep_for(std::chrono::milliseconds(50));
    });
    
    for (int i = 0; i < 5; ++i) {
        pool.execute([]() {
            std::this_thread::sleep_for(std::chrono::milliseconds(100));
        });
    }
    
    // 等待第一个任务开始执行
    std::this_thread::sleep_for(std::chrono::milliseconds(60));
    
    // 清空任务队列
    pool.clearTasks();
    
    // 验证队列为空
    EXPECT_TRUE(pool.isEmpty());
    
    // 等待正在执行的任务完成
    std::this_thread::sleep_for(std::chrono::milliseconds(100));
    
    pool.shutdown();
}

// 线程池信息获取测试
TEST(ThreadPoolTest, GetInfo) {
    ThreadPool pool(3, "InfoTestPool");
    pool.start();
    
    // 验证线程池名称
    EXPECT_EQ(pool.name(), "InfoTestPool");
    
    // 验证初始线程数
    EXPECT_EQ(pool.threadCount(), 3);
    
    // 初始活跃线程数应为0
    EXPECT_EQ(pool.activeThreadCount(), 0);
    
    // 提交一些任务并检查活跃线程数
    std::vector<std::future<void>> futures;
    for (int i = 0; i < 5; ++i) {
        futures.push_back(pool.submit([]() {
            std::this_thread::sleep_for(std::chrono::milliseconds(20));
        }));
    }
    
    // 短暂等待，让任务开始执行
    std::this_thread::sleep_for(std::chrono::milliseconds(5));
    
    // 活跃线程数应该大于0，但具体数目取决于调度
    EXPECT_GT(pool.activeThreadCount(), 0);
    
    // 等待所有任务完成
    for (auto& future : futures) {
        future.wait();
    }
    
    // 任务完成后活跃线程数应为0
    EXPECT_EQ(pool.activeThreadCount(), 0);
    
    pool.shutdown();
}

} // namespace test
} // namespace cytoolkit

int main(int argc, char** argv) {
    testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}